package tracer

import (
	"context"

	"gitee.com/go-course/go11/devcloud-mini/mcenter/conf"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/jaeger"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
	oteltrace "go.opentelemetry.io/otel/trace"
)

// 全局Tracer对象
var Tracer oteltrace.Tracer

// 记得调用初始化方法，初始化全局Tracer对象
func InitTracer() error {
	ep := conf.C().Jaeger.Endpoint

	// 如果没配置就不启动Tracer
	if ep == "" {
		return nil
	}

	exporter, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(ep)))
	if err != nil {
		return err
	}

	// 初始化一个Provider, 设置具体的Provider(Jaeger/zipkin/...)
	// 这里我们选择Jaeger
	tp := sdktrace.NewTracerProvider(
		// 直接使用的
		sdktrace.WithSampler(sdktrace.AlwaysSample()),
		//  指定Provider： Jaeger
		sdktrace.WithBatcher(exporter),
		// Traces时需要携带的额外数据(Pod Name), 需要携带的数据定义为Resource
		sdktrace.WithResource(newResource()),
	)
	// 通过SetTracerProvider 把当前的TraceProvider 赋值为一个全局Provider
	otel.SetTracerProvider(tp)

	// 上下文数据如何传递,  相当于初始化了一个Root Context
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{}))

	// 通过全局的Provider, 在Cmdb服务内部运行的Traccer, CMDB Tracer
	// Trace 来来自于cmdb的请求
	Tracer = otel.GetTracerProvider().Tracer("mcenter", oteltrace.WithInstrumentationVersion("0.1"))
	return nil
}

// newResource returns a resource describing this application.
func newResource() *resource.Resource {
	// 因为需要手动设置ServiceName和版本, 不使用default的自动探测
	// resource.Default()

	r, _ := resource.New(
		context.Background(),
		resource.WithFromEnv(),
		resource.WithTelemetrySDK(),
		resource.WithAttributes(
			semconv.ServiceNameKey.String("mcenter"),
			semconv.ServiceVersionKey.String("1.0"),
		),
	)
	return r
}
